{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "sT8AyHRMNh41"
   },
   "source": [
    "# TensorFlow Recommenders: Quickstart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "8f-reQ11gbLB"
   },
   "source": [
    "In this tutorial, we build a simple matrix factorization model using the [MovieLens 100K dataset](https://grouplens.org/datasets/movielens/100k/) with TFRS. We can use this model to recommend movies for a given user."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Import TensorFlow Recommender System (TFRS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -q sagemaker==2.9.2\n",
    "!pip install -q sagemaker-experiments==0.1.24\n",
    "!pip install -q tensorflow==2.3.0\n",
    "!pip install -q tensorflow-recommenders==0.2.0\n",
    "!pip install -q tensorflow-datasets==4.0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "n3oYt3R6Nr9l"
   },
   "outputs": [],
   "source": [
    "from typing import Dict, Text\n",
    "\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "\n",
    "import tensorflow_datasets as tfds\n",
    "import tensorflow_recommenders as tfrs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RankingModel(tf.keras.Model):\n",
    "\n",
    "  def __init__(self, embedding_dimension, unique_user_ids, unique_movie_titles):\n",
    "    super().__init__()\n",
    "\n",
    "    # Compute embeddings for users.\n",
    "    self.user_model = tf.keras.Sequential([\n",
    "      tf.keras.layers.experimental.preprocessing.StringLookup(\n",
    "        vocabulary=unique_user_ids, mask_token=None),\n",
    "      tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)\n",
    "    ])\n",
    "\n",
    "    # Compute embeddings for movies.\n",
    "    self.movie_model = tf.keras.Sequential([\n",
    "      tf.keras.layers.experimental.preprocessing.StringLookup(\n",
    "        vocabulary=unique_movie_titles, mask_token=None),\n",
    "      tf.keras.layers.Embedding(len(unique_movie_titles) + 1, embedding_dimension)\n",
    "    ])\n",
    "\n",
    "    # Compute predictions.\n",
    "    self.ratings = tf.keras.Sequential([\n",
    "      # Learn multiple dense layers.\n",
    "      tf.keras.layers.Dense(256, activation=\"relu\"),\n",
    "      tf.keras.layers.Dense(64, activation=\"relu\"),\n",
    "      # Make rating predictions in the final layer.\n",
    "      tf.keras.layers.Dense(1)\n",
    "  ])\n",
    "    \n",
    "  def call(self, inputs):\n",
    "\n",
    "    user_id, movie_title = inputs\n",
    "\n",
    "    user_model = self.user_model(user_id)\n",
    "    movie_model = self.movie_model(movie_title)\n",
    "\n",
    "    return self.ratings(tf.concat([user_model, movie_model], axis=1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MovielensModel(tfrs.models.Model):\n",
    "\n",
    "  def __init__(self, embedding_dimension, unique_user_ids, unique_movie_titles):\n",
    "    super().__init__()\n",
    "    self.ranking_model: tf.keras.Model = RankingModel(embedding_dimension, unique_user_ids, unique_movie_titles)\n",
    "    self.task: tf.keras.layers.Layer = tfrs.tasks.Ranking(\n",
    "      loss = tf.keras.losses.MeanSquaredError(),\n",
    "      metrics=[tf.keras.metrics.RootMeanSquaredError()]\n",
    "    )\n",
    "\n",
    "  def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:\n",
    "    rating_predictions = self.ranking_model(\n",
    "        (features[\"user_id\"], features[\"movie_title\"]))\n",
    "\n",
    "    # The task computes the loss and the metrics.\n",
    "    return self.task(labels=features[\"user_rating\"], predictions=rating_predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "zCxQ1CZcO2wh"
   },
   "source": [
    "# Load Ratings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "M-mxBYjdO5m7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<PrefetchDataset shapes: {bucketized_user_age: (), movie_genres: (None,), movie_id: (), movie_title: (), raw_user_age: (), timestamp: (), user_gender: (), user_id: (), user_occupation_label: (), user_occupation_text: (), user_rating: (), user_zip_code: ()}, types: {bucketized_user_age: tf.float32, movie_genres: tf.int64, movie_id: tf.string, movie_title: tf.string, raw_user_age: tf.float32, timestamp: tf.int64, user_gender: tf.bool, user_id: tf.string, user_occupation_label: tf.int64, user_occupation_text: tf.string, user_rating: tf.float32, user_zip_code: tf.string}>\n"
     ]
    }
   ],
   "source": [
    "ratings = tfds.load('movielens/100k-ratings',                     \n",
    "                    download=False,\n",
    "                    data_dir='./tensorflow_datasets/',\n",
    "                    split='train')\n",
    "print(ratings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<MapDataset shapes: {movie_title: (), user_id: (), user_rating: ()}, types: {movie_title: tf.string, user_id: tf.string, user_rating: tf.float32}>\n"
     ]
    }
   ],
   "source": [
    "ratings = ratings.map(lambda x: {\n",
    "    \"movie_title\": x[\"movie_title\"],\n",
    "    \"user_id\": x[\"user_id\"],\n",
    "    \"user_rating\": x[\"user_rating\"]\n",
    "})\n",
    "print(ratings)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Load Movies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Movies BEFORE <PrefetchDataset shapes: {movie_genres: (None,), movie_id: (), movie_title: ()}, types: {movie_genres: tf.int64, movie_id: tf.string, movie_title: tf.string}>\n"
     ]
    }
   ],
   "source": [
    "movies = tfds.load('movielens/100k-movies', \n",
    "                   download=False,                   \n",
    "                   data_dir='./tensorflow_datasets/',\n",
    "                   split='train')\n",
    "print('Movies BEFORE', movies)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Movies AFTER <MapDataset shapes: (), types: tf.string>\n"
     ]
    }
   ],
   "source": [
    "movies = movies.map(lambda x: x[\"movie_title\"])\n",
    "print('Movies AFTER', movies)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.random.set_seed(42)\n",
    "shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)\n",
    "\n",
    "train = shuffled.take(80_000)\n",
    "test = shuffled.skip(80_000).take(20_000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "movie_titles = ratings.batch(100_000).map(lambda x: x[\"movie_title\"])\n",
    "user_ids = ratings.batch(100_000).map(lambda x: x[\"user_id\"])\n",
    "\n",
    "unique_movie_titles = np.unique(np.concatenate(list(movie_titles)))\n",
    "unique_user_ids = np.unique(np.concatenate(list(user_ids)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "embedding_dimension = 32"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# task = tfrs.tasks.Ranking(\n",
    "#   loss = tf.keras.losses.MeanSquaredError(),\n",
    "#   metrics=[tf.keras.metrics.RootMeanSquaredError()]\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = MovielensModel(embedding_dimension, unique_user_ids, unique_movie_titles)\n",
    "model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "cached_train = train.shuffle(100_000).batch(8192).cache()\n",
    "cached_test = test.batch(4096).cache()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "epochs = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10/10 [==============================] - 0s 44ms/step - root_mean_squared_error: 2.1126 - loss: 4.1097 - regularization_loss: 0.0000e+00 - total_loss: 4.1097\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x7fe17dbe7710>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(cached_train, epochs=epochs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5/5 [==============================] - 0s 13ms/step - root_mean_squared_error: 1.1334 - loss: 1.2790 - regularization_loss: 0.0000e+00 - total_loss: 1.2790\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'root_mean_squared_error': 1.1334493160247803,\n",
       " 'loss': 1.2540225982666016,\n",
       " 'regularization_loss': 0,\n",
       " 'total_loss': 1.2540225982666016}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(cached_test, return_dict=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Make Predictions\n",
    "Use brute-force search to set up retrieval using the trained representations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow_recommenders.layers.factorized_top_k.BruteForce at 0x7fe17dc3fd90>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index = tfrs.layers.factorized_top_k.BruteForce(model.ranking_model.user_model)\n",
    "index.index(movies.batch(100).map(model.ranking_model.movie_model), movies)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "local_model_dir_bruteforce_model = './exported_models/bruteforce_model/'\n",
    "\n",
    "tensorflow_saved_model_path_bruteforce_model = os.path.join(local_model_dir_bruteforce_model, 'tensorflow/saved_model/0')\n",
    "\n",
    "os.makedirs(tensorflow_saved_model_path_bruteforce_model, exist_ok=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top 5 recommendations for user 42: [b'Strawberry and Chocolate (Fresa y chocolate) (1993)'\n",
      " b'Murder, My Sweet (1944)'\n",
      " b\"Don't Be a Menace to South Central While Drinking Your Juice in the Hood (1996)\"\n",
      " b'In the Mouth of Madness (1995)' b'Richie Rich (1994)']\n"
     ]
    }
   ],
   "source": [
    "k = 5\n",
    "user_id = \"42\"\n",
    "\n",
    "_, titles = index(np.array([user_id]))\n",
    "\n",
    "print(f\"Top {k} recommendations for user {user_id}: {titles[0, :k]}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Compiled model <tensorflow_recommenders.layers.factorized_top_k.BruteForce object at 0x7fe17dc3fd90>\n",
      "Model: \"brute_force\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "sequential (Sequential)      (None, 32)                30208     \n",
      "=================================================================\n",
      "Total params: 85,714\n",
      "Trainable params: 30,208\n",
      "Non-trainable params: 55,506\n",
      "_________________________________________________________________\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print('Compiled model {}'.format(index))          \n",
    "print(index.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets written to: ./exported_models/bruteforce_model/tensorflow/saved_model/0/assets\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets written to: ./exported_models/bruteforce_model/tensorflow/saved_model/0/assets\n"
     ]
    }
   ],
   "source": [
    "index.save(tensorflow_saved_model_path_bruteforce_model, save_format='tf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2020-11-29 23:26:47.733062: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcudart.so.10.1'; dlerror: libcudart.so.10.1: cannot open shared object file: No such file or directory\n",
      "2020-11-29 23:26:47.733109: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n",
      "\n",
      "MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:\n",
      "\n",
      "signature_def['__saved_model_init_op']:\n",
      "  The given SavedModel SignatureDef contains the following input(s):\n",
      "  The given SavedModel SignatureDef contains the following output(s):\n",
      "    outputs['__saved_model_init_op'] tensor_info:\n",
      "        dtype: DT_INVALID\n",
      "        shape: unknown_rank\n",
      "        name: NoOp\n",
      "  Method name is: \n",
      "\n",
      "signature_def['serving_default']:\n",
      "  The given SavedModel SignatureDef contains the following input(s):\n",
      "    inputs['input_1'] tensor_info:\n",
      "        dtype: DT_STRING\n",
      "        shape: (-1)\n",
      "        name: serving_default_input_1:0\n",
      "  The given SavedModel SignatureDef contains the following output(s):\n",
      "    outputs['output_1'] tensor_info:\n",
      "        dtype: DT_FLOAT\n",
      "        shape: (-1, 10)\n",
      "        name: StatefulPartitionedCall:0\n",
      "    outputs['output_2'] tensor_info:\n",
      "        dtype: DT_STRING\n",
      "        shape: (-1, 10)\n",
      "        name: StatefulPartitionedCall:1\n",
      "  Method name is: tensorflow/serving/predict\n",
      "2020-11-29 23:26:49.425243: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2020-11-29 23:26:49.425299: W tensorflow/stream_executor/cuda/cuda_driver.cc:312] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2020-11-29 23:26:49.425337: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (datascience-1-0-ml-t3-medium-1abf3407f667f989be9d86559395): /proc/driver/nvidia/version does not exist\n",
      "Traceback (most recent call last):\n",
      "  File \"/opt/conda/bin/saved_model_cli\", line 8, in <module>\n",
      "    sys.exit(main())\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/tools/saved_model_cli.py\", line 1185, in main\n",
      "    args.func(args)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/tools/saved_model_cli.py\", line 715, in show\n",
      "    _show_all(args.dir)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/tools/saved_model_cli.py\", line 307, in _show_all\n",
      "    _show_defined_functions(saved_model_dir)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/tools/saved_model_cli.py\", line 187, in _show_defined_functions\n",
      "    trackable_object = load.load(saved_model_dir)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py\", line 603, in load\n",
      "    return load_internal(export_dir, tags, options)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py\", line 633, in load_internal\n",
      "    ckpt_options)\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py\", line 131, in __init__\n",
      "    self._restore_checkpoint()\n",
      "  File \"/opt/conda/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py\", line 358, in _restore_checkpoint\n",
      "    \"%r from the checkpoint.\" % obj))\n",
      "NotImplementedError: Missing functionality to restore state of object <tensorflow.python.saved_model.load._RestoredResource object at 0x7f75df9ca510> from the checkpoint.\n"
     ]
    }
   ],
   "source": [
    "!saved_model_cli show --all --dir $tensorflow_saved_model_path_bruteforce_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2020-11-29 23:26:50.660452: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcudart.so.10.1'; dlerror: libcudart.so.10.1: cannot open shared object file: No such file or directory\n",
      "2020-11-29 23:26:50.660517: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n",
      "2020-11-29 23:26:52.180553: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2020-11-29 23:26:52.180596: W tensorflow/stream_executor/cuda/cuda_driver.cc:312] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2020-11-29 23:26:52.180644: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (datascience-1-0-ml-t3-medium-1abf3407f667f989be9d86559395): /proc/driver/nvidia/version does not exist\n",
      "2020-11-29 23:26:52.180917: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "2020-11-29 23:26:52.187922: I tensorflow/core/platform/profile_utils/cpu_utils.cc:104] CPU Frequency: 2499995000 Hz\n",
      "2020-11-29 23:26:52.188136: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x556c1982efb0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:\n",
      "2020-11-29 23:26:52.188167: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version\n",
      "WARNING:tensorflow:From /opt/conda/lib/python3.7/site-packages/tensorflow/python/tools/saved_model_cli.py:444: load (from tensorflow.python.saved_model.loader_impl) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.loader.load or tf.compat.v1.saved_model.load. There will be a new function for importing SavedModels in Tensorflow 2.0.\n",
      "INFO:tensorflow:Restoring parameters from ./model/tensorflow/saved_model/0/variables/variables\n",
      "Result for output key output_1:\n",
      "[[0.01571999 0.01323595 0.012932   0.01239091 0.01233906 0.01191704\n",
      "  0.01171806 0.01165831 0.01142757 0.01099861]]\n",
      "Result for output key output_2:\n",
      "[[b'Twilight (1998)' b'Mortal Kombat: Annihilation (1997)'\n",
      "  b'Mary Reilly (1996)' b'Stag (1997)' b'Pushing Hands (1992)'\n",
      "  b'American Strays (1996)' b'Flesh and Bone (1993)' b'Carrie (1976)'\n",
      "  b'Forget Paris (1995)' b'So I Married an Axe Murderer (1993)']]\n"
     ]
    }
   ],
   "source": [
    "user_id = \"42\"\n",
    "\n",
    "!saved_model_cli run --input_exprs 'input_1=np.array([\"$user_id\"])' --tag_set serve --signature_def serving_default --dir ./model/tensorflow/saved_model/0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "quickstart.ipynb",
   "private_outputs": true,
   "provenance": [],
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3 (Data Science)",
   "language": "python",
   "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
